package br.com.foxinline.servico;

import br.com.foxinline.enums.Banco;
import br.com.foxinline.enums.Relatorio;
import br.com.foxinline.enums.Taxas;
import br.com.foxinline.generico.ServicoGenerico;
import br.com.foxinline.modelo.Anexo;
import br.com.foxinline.modelo.Bairro;
import br.com.foxinline.modelo.Cidade;
import br.com.foxinline.modelo.Endereco;
import br.com.foxinline.modelo.Prefeitura;
import br.com.foxinline.util.GrupoUtilitario;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.security.DeclareRoles;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
@DeclareRoles(GrupoUtilitario.ADMINISTRADOR)
public class PrefeituraServico extends ServicoGenerico<Prefeitura> {

    @EJB
    private UsuarioServico usuarioServico;
    @EJB
    private CidadeServico cidadeServico;
    @EJB
    private AnexoServico anexoServico;

    public PrefeituraServico() {
        super(Prefeitura.class);
    }

    public Prefeitura find() {
        return find(null);
    }

    @Override
    public void update(Prefeitura entity) {
        super.update(entity);
        updateAnexos(entity);
    }

    @Override
    public void updateAnexos(Prefeitura p) {
        p.setLogo(getLogo(p));
        p.setLogoRegularizacaoFundiaria(getLogoRegularizacaoFundiaria(p));
        super.updateAnexos(p);
    }

    @Override
    public Prefeitura find(Long entityID) {
        return findAll().get(0);
    }

    @Override
    public List<Prefeitura> findAll() {

        List<Prefeitura> prefeituras = super.findAll();

        if (prefeituras != null && !prefeituras.isEmpty()) {
            Prefeitura prefeitura = prefeituras.get(0);

            prefeituras = new ArrayList<Prefeitura>();
            prefeituras.add(prefeitura);

            return prefeituras;
        }

        prefeituras = new ArrayList<Prefeitura>();
        prefeituras.add(prefeituraPadrao());

        return prefeituras;
    }

    public Map<String, Object> parametroPrefeitura() {
        HashMap parametros = new HashMap();

        Prefeitura prefeitura = find(null);

        parametros.put("nomePrefeitura", prefeitura.getNome().toUpperCase());
        parametros.put("secretariaPrefeitura", prefeitura.getSecretariaRegularizacaoFundiaria().toUpperCase());
        parametros.put("nomeEngenheiroPrefeitura", prefeitura.getNomeEngenheiroAgrimensor().toUpperCase());
        parametros.put("creaEngenheiroPrefeitura", prefeitura.getCreaEngenheiroAgrimensor().toUpperCase());

        if (prefeitura.getLogo() != null) {

            if (prefeitura.getLogo().getUrl() != null) {

                parametros.put("logoUrlPrefeitura", prefeitura.getLogo().getUrl().concat(prefeitura.getLogo().getNome()));
            }
        }

        if (prefeitura.getLogoRegularizacaoFundiaria() != null) {

            if (prefeitura.getLogoRegularizacaoFundiaria().getUrl() != null) {

                parametros.put("logoUrlFundiaria", prefeitura.getLogoRegularizacaoFundiaria().getUrl().concat(prefeitura.getLogoRegularizacaoFundiaria().getNome()));
            }
        }

        if (prefeitura.getEndereco() != null && prefeitura.getEndereco().getUf() != null && !prefeitura.getEndereco().getUf().isEmpty()) {

            parametros.put("estadoSiglaPrefeitura", prefeitura.getEndereco().getUf().toUpperCase());
        }

        URL rodape = Thread.currentThread().getContextClassLoader().getResource("br/com/foxinline/relatorio/rodape_subreport.jasper");
        URL cabecalho = Thread.currentThread().getContextClassLoader().getResource("br/com/foxinline/relatorio/cabecalho_subreport.jasper");

        parametros.put("RODAPE_SUBREPORT", rodape.toString());
        parametros.put("CABECALHO_SUBREPORT", cabecalho.toString());

        return parametros;
    }

    public String getCentroMapa() {
        return find().getCentroMapa();
    }

    public Integer getZoomMapa() {
        return find().getZoomMapa();
    }

    public Prefeitura getPrefeituraAtual() {
        return (Prefeitura) super.getEntityManager().createQuery("select p from " + Prefeitura.class.getSimpleName() + " p order by p.id DESC").getResultList().get(0);
    }

    public List<Object[]> findBoletimArrecadacao(Date ini, Date fim) {
        String sql = "select "
                + "p.nomebanco, "
                + "p.codigobanco, "
                + "p.contabanco, "
                + "p.codigoagencia, "
                + "p.codigoimposto, "
                + "count(p), "
                + "sum(p.valortarifa), "
                + "sum(p.valor) "
                + "from parcela p "
                + "where p.pago = true ";

        SimpleDateFormat sdf = new SimpleDateFormat();
        if (ini != null && fim != null) {
            sdf.applyPattern("yyyy/MM/dd");
            sql += " and p.datacredito between " + "'" + sdf.format(ini) + "'" + " and " + "'" + sdf.format(fim) + "'";
        }

        sql += " group by p.contabanco, p.codigoagencia, p.nomebanco, p.codigobanco, p.codigoimposto";
        sql += " order by p.contabanco, p.codigoagencia, p.codigobanco";

        Query query = getEntityManager().createNativeQuery(sql);

        return query.getResultList();
    }

    public void imprimirBoletimArrecadacao(List<Object[]> results, HashMap parametros) {
        Prefeitura prefeitura = find(null);

        URL rodape = Thread.currentThread().getContextClassLoader().getResource("br/com/foxinline/relatorio/rodape_subreport.jasper");
        URL cabecalho = Thread.currentThread().getContextClassLoader().getResource("br/com/foxinline/relatorio/cabecalho_subreport.jasper");

        parametros.put("RODAPE_SUBREPORT", rodape.toString());
        parametros.put("CABECALHO_SUBREPORT", cabecalho.toString());
        parametros.put("titulo", "Departamento de Contabilidade");
        parametros.put("subTitulo", "Boletim Diário de Arrecadação Resumido");
        parametros.put("nomePrefeitura", prefeitura.getNome().toUpperCase());
        parametros.put("usuario", usuarioServico.getCurrentUser().getNome());

        if (prefeitura.getLogo() != null) {

            if (prefeitura.getLogo().getUrl() != null) {
                parametros.put("logoUrlPrefeitura", prefeitura.getLogo().getUrl().concat(prefeitura.getLogo().getNome()));
            }
        }

        List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();

        HashMap<Integer, String> taxas = new HashMap<Integer, String>();
        for (Taxas taxa : Taxas.values()) {
            taxas.put(taxa.getValor(), taxa.getNome());
        }

        for (Object[] objects : results) {
            HashMap<String, Object> map = new HashMap<String, Object>();

            map.put("nomeBanco", objects[0]);
            map.put("banco", objects[1]);
            map.put("conta", objects[2]);
            map.put("agencia", objects[3]);
            map.put("imposto", objects[4]);
            map.put("tributo", taxas.containsKey(objects[4]) ? taxas.get(objects[4]) : "-");
            map.put("qtdParcelas", objects[5]);
            map.put("vlrTarifaTotal", objects[6]);
            map.put("vlrTotal", objects[7]);
            list.add(map);
        }

        RelatorioServico.genReport(parametros, list, Relatorio.BOLETIM_ARRECADACAO_RESUMIDO);
    }

    private Prefeitura prefeituraPadrao() {
        Prefeitura p = new Prefeitura();
        p.setNome("");
        p.setSecretariaRegularizacaoFundiaria("");
        p.setNomeEngenheiroAgrimensor("");
        p.setCreaEngenheiroAgrimensor("");
        p.setCentroMapa("-2.9136, -41.7577");
        p.setZoomMapa(13);
        p.setDesabilitarMapas(false);
        p.setLogo(this.anexoServico.getAnexoPadrao());
        p.setLogoRegularizacaoFundiaria(this.anexoServico.getAnexoPadrao());
        Cidade c = (Cidade) this.cidadeServico.findByNameEstado("parnaíba", "PI").get(0);
        Bairro b = new Bairro();
        b.setCidade(c);
        Endereco end = new Endereco();
        end.setBairroDne(b);
        p.setEndereco(end);
        p.setBanco(Banco.BANCO_BRASIL);
        p.setBancoAgencia("");
        p.setBancoCarteira("");
        p.setBancoConta("");
        p.setBancoNumeroConvenio("");
        return p;
    }

    private Anexo getLogo(Prefeitura p) {
        String sql = "select a from " + Prefeitura.class.getSimpleName() + " p join p.logo a where p.id = " + p.getId();

        try {
            return (Anexo) getEntityManager().createQuery(sql).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    private Anexo getLogoRegularizacaoFundiaria(Prefeitura p) {
        String sql = "select a from " + Prefeitura.class.getSimpleName() + " p join p.logoRegularizacaoFundiaria a where p.id = " + p.getId();

        try {
            return (Anexo) getEntityManager().createQuery(sql).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }
}
